//
//  TokenBucket.m
//  CareRingApp
//
//  Created  on 2025/3/13.
//  用于超时计时
    

#import "TokenBucket.h"

@interface TokenBucket()

@property(atomic, assign) NSUInteger tokens;// 令牌

@property(strong, nonatomic)dispatch_source_t timer;
@property(strong, nonatomic)dispatch_queue_t queue;

@end

@implementation TokenBucket
-(instancetype)init
{
    if (self = [super init])
    {
        self.queue = dispatch_queue_create("TokBktSQueue", DISPATCH_QUEUE_SERIAL);
    }
    return self;
}


-(BOOL)start
{
    if (self.tokenCount == 0 || self.intervalSecs == 0)
    {
        return NO;
    }
    
    if (self.timer) {
        DebugNSLog(@"令牌桶已启动");
        return NO;
    }
//    DebugNSLog(@"令牌桶启动");
    self.tokens = self.tokenCount; //令牌桶充满
    
    if (self.timer) {
        dispatch_source_cancel(self.timer);
        self.timer = nil;
    }
    
    __weak typeof(self) weakSelf = self;
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue);
    
    dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, self.intervalSecs * NSEC_PER_SEC, 0.01 * NSEC_PER_SEC);
    
    dispatch_source_set_event_handler(self.timer, ^{
        // 检查令牌桶
        __strong typeof(weakSelf) strongSelf = weakSelf;
//        DebugNSLog(@"令牌桶 减1");

        strongSelf.tokens--;
        if (strongSelf.tokens <= 0) {
            if (strongSelf.timeoutBlock) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    __strong typeof(weakSelf) strongSelf = weakSelf;
                    strongSelf.timeoutBlock();
                });
            }
            
            [strongSelf stop];
            return;
        }
        
    });
    dispatch_activate(self.timer);
    
    return YES;
}

-(void)stop
{
    
    if (self.timer) {
        dispatch_source_cancel(self.timer);
        self.timer = nil;
    }
    
    
    
}

-(void)chargeToken
{
    
//    return;
    __weak typeof(self) weakSelf = self;

    dispatch_async(self.queue, ^{
//        DebugNSLog(@"令牌桶 充值");
        __strong typeof(weakSelf) strongSelf = weakSelf;
        strongSelf.tokens = strongSelf.tokenCount; //令牌桶充满

    });
}


@end
